﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication1.segments;

namespace ConsoleApplication1
{
    class segment
    {
        public msh Message_heder { get; set; }
        public PID patient_Identification { get; set; }
        public enum segments { DG1, EVN, MSH, OBX, ORC, PID, PV1, RXO, NTE, OBR }
        public  string check(string source, int temp)
        {

            if (source[temp].ToString() + source[temp + 1].ToString() + source[temp + 2].ToString() == segments.MSH.ToString())
                return segments.MSH.ToString();
            else if (source[temp].ToString() + source[temp + 1].ToString() + source[temp + 2].ToString() == segments.DG1.ToString())
                return segments.DG1.ToString();
            else if (source[temp].ToString() + source[temp + 1].ToString() + source[temp + 2].ToString() == segments.EVN.ToString())
                return segments.EVN.ToString();
            else if (source[temp].ToString() + source[temp + 1].ToString() + source[temp + 2].ToString() == segments.NTE.ToString())
                return segments.NTE.ToString();
            else if (source[temp].ToString() + source[temp + 1].ToString() + source[temp + 2].ToString() == segments.OBR.ToString())
                return segments.OBR.ToString();
            else if (source[temp].ToString() + source[temp + 1].ToString() + source[temp + 2].ToString() == segments.OBX.ToString())
                return segments.OBX.ToString();
            else if (source[temp].ToString() + source[temp + 1].ToString() + source[temp + 2].ToString() == segments.ORC.ToString())
                return segments.ORC.ToString();
            else if (source[temp].ToString() + source[temp + 1].ToString() + source[temp + 2].ToString() == segments.PID.ToString())
                return segments.PID.ToString();
            else if (source[temp].ToString() + source[temp + 1].ToString() + source[temp + 2].ToString() == segments.PV1.ToString())
                return segments.PV1.ToString();
            else if (source[temp].ToString() + source[temp + 1].ToString() + source[temp + 2].ToString() == segments.RXO.ToString())
                return segments.RXO.ToString();

            return null;
        }
    }
    class ACK : segment
    {
        enum Acknowledgement_code { AA/*	Application Accept*/, AE/*	Application Error*/, AR/*Application Reject*/}

        public void send(msh msh,int cond)
        {
            Message_heder = msh;
            Message_heder.date = DateTime.Now.Date.ToString();
            Message_heder.message_type.message_type.Remove(0,Message_heder.message_type.message_type.Length);
            Message_heder.message_type.message_type.Insert(0, "ACK");
            Message_heder.Sending_Application = Message_heder.Receiving_Application;
            Message_heder.Receiving_Application.application_identifier.Remove(0,Message_heder.Receiving_Application.application_identifier.Length);
            Message_heder.Receiving_Application.application_identifier.Insert(0, "sendhl7");
            Message_heder.required = true;

            MSA msa=new MSA();
            string ack_code = "";

            if (cond == 1)
                ack_code = Acknowledgement_code.AA.ToString();
            else if (cond == 2)
                ack_code = Acknowledgement_code.AE.ToString(); // msa.Text_Message lesa mat3mltysh
            else if (cond == 3)
                ack_code = Acknowledgement_code.AR.ToString();

            msa.Acknowledgement_code.Insert(0, ack_code);
            msa.Message_Control_ID = Message_heder.message_control_id;
            
            connection con = new connection();
            string temp = Message_heder.tostring() + msa.tostring();
            con.send(temp);
            Console.WriteLine(temp);


        }
    }

    class ORM:segment
    {
        private string source;
        enum segments { DG1, EVN, MSH, OBX, ORC, PID, PV1, RXO, NTE, OBR }

        public ORC orc { get; set; }
        public DG1 dg1 { get; set; }
        public PV1 pv1 { get; set; }
        public NTE nte { get; set; }

        public List<NTE> nte_list { get; set; }

        public ORM()
        {
        }
         public ORM(string source1)
        {
            source = source1;
        }
         public void fill()
         {
             int string_length = source.Length;
             string temp = "";

             ACK ack = new ACK();

             for (int i = 0; i < source.Length; i++)
             {
                 if (source[i] == '|')
                     continue;
                 else if (i + 3 == source.Length)
                     break;
                 else
                     temp = check(source, i);
                 if (temp == null)
                     continue;
                 else
                 {
                     switch (temp)
                     {
                         case "MSH":
                             Message_heder = new msh();
                             i = Message_heder.fill(source, i + 3);
                             break;
                         case "PID":
                             patient_Identification = new PID();
                             i = patient_Identification.fill(source, i + 3);
                             break;
                         case "ORC":
                             orc = new  ORC ();
                             i = orc.fill(source, i + 3);
                             break;
                         case "DG1":
                             dg1 = new DG1();
                             i = dg1.fill(source, i + 3);
                             break;
                         case "PV1":

                              pv1 = new PV1();
                              i = pv1.fill(source, i + 3);
                             break;
                         case "NTE":
                             nte = new NTE();
                             i = nte.fill(source, i + 3);
                             nte_list.Add(nte);
                             break;
                         default:
                             Console.WriteLine("unknown segment " + source[i] + source[i + 1] + source[i + 2]);
                             break;
                     }
                 }
                 //else 
                 //    break;
             }
             ack.send(Message_heder, 1); 
         }

         public void send()
         {
             string orm_string = "";
             
             orm_string+= Message_heder.tostring(); // required 
             orm_string+= patient_Identification.tostring(); //requireed

             orm_string += orc.ToString();
             orm_string += dg1.ToString();
             orm_string += pv1.ToString();
             foreach (NTE item in nte_list)
             {
                 orm_string += item.ToString();
             }

             connection con = new connection();

             con.send(orm_string);
             Console.WriteLine(orm_string);
         }
    }
    class ORU : segment
    {
        public PV1 Patient_visit { get; set; }
        public ORC common_order { get; set; }
        public OBX Observation_request { get; set; }
        public NTE 	Notes_and_Comments { get; set; }
        public List<NTE> nte_list { get; set; }

        public List<OBX> obx { get; set; }

        private string source;


        public ORU(string source1)
        {
            source=source1  ;
            nte_list = new List<NTE>();
            obx=new List<OBX>();
        }


        public void fill()
        {
            ACK ack = new ACK();
            string temp;
        //    try
            {
                for (int i = 0; i < source.Length; i++)
                {
                    if (source[i]=='|')
                        continue;
                    else if (i + 4 >= source.Length)
                        break;
                    else
                        temp =check(source,i);
                    if (temp == null)
                            continue;
                    else
                    {
                        switch (temp)
                        {
                            case "MSH":
                                Message_heder = new msh();
                                i = Message_heder.fill(source, i + 3);
                                break;
                            case "PID":
                                patient_Identification = new PID();
                                i = patient_Identification.fill(source, i + 3);
                                break;
                            case "PV1":
                                 Patient_visit = new PV1();
                                 i = Patient_visit.fill(source, i + 3);
                                break;
                            case "ORC":
                                common_order = new ORC();
                                i = common_order.fill(source, i + 3);
                                break;
                            case "OBX":
                                    
                                Observation_request = new OBX();
                                i = Observation_request.fill(source, i + 3);
                               obx.Add(Observation_request);
                                break;
                            case "NTE":
                                Notes_and_Comments = new NTE();
                                i = Notes_and_Comments.fill(source, i + 3);
                                nte_list.Add(Notes_and_Comments);
                                break;
                            default:
                                Console.WriteLine("unknown segment "+source[i]+source[i+1]+source[i+2]);
                                break;
                        }
                    }
                }
            }
                  
       //     catch (Exception e)
            {

          //      ack.send(Message_heder, 2);
           //     Console.WriteLine(e.ToString());
            }
        
            ack.send(Message_heder, 1);
        }

        public void send ()
        {
            string oru_string = "";
            oru_string += Message_heder.tostring(); // required 
            oru_string += patient_Identification.tostring(); //requireed

            foreach (OBX item in obx)
            {
                oru_string += item.ToString();
            }
            oru_string += Patient_visit.ToString();
            oru_string += common_order.ToString();

            foreach (NTE item in nte_list)
            {
                oru_string += item.ToString();
            }

            connection con = new connection();

            con.send(oru_string);
            Console.WriteLine(oru_string);
        }
    }

    class ADT : segment
    {
        public EVN Event { get; set; }
        public PV1 patient_visit{ get; set; }
        public DG1 diagnosis { get; set; }
    }

}
